package com.lucky;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;

@Component
@Slf4j
public class Niuniu implements SchedulingConfigurer {
    @Value("${chromedriver.driver}")
    private String driver;
    @Value("${erp.url}")
    private String url;

    private static boolean status = true;//true 上 false
    private static int count;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        checkPwd(true);
        taskRegistrar.addTriggerTask(doTask(), getTrigger());
    }

    /**
     * 主要业务
     */
    public Runnable doTask() {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    boolean flag = getHoliday();
                    if (flag) {
                        WebDriver driver = checkPwd(false);
                        TimeUnit.SECONDS.sleep(3);
                        if (status) {
                            driver.findElement(By.className("check-in")).click();
                            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            log.info("现在时间是:" + dateFormat.format(System.currentTimeMillis()) + ", 欢迎收看今天的新闻联播内容");
                            status = false;
                        } else {
                            driver.findElement(By.className("check-in")).click();
                            log.info(new Date(System.currentTimeMillis()) + "今天的新闻联播播送完了,感谢您的收看,拒绝内卷,让美好如期而至！");
                            status = true;
                        }
                        driver.quit();
                    } else {
                        log.info("根据《国务院办公厅关于严格执行国家法定节假日有关规定的通知》,今日为法定节假日！请认真遵照国务院通知要求，严格执行有关规定!");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.info("warning！warning！warning！(语音警告中...)");
                }
            }
        };
    }

    /**
     * 触发器
     */
    private Trigger getTrigger() {
        return new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                CronTrigger trigger = new CronTrigger(getCron());
                return trigger.nextExecutionTime(triggerContext);
            }
        };
    }

    /**
     * 定制定时任务
     */
    public String getCron() {
        String cron = "";
        ConfigDTO config = readUserFile();
        try {
            Integer hour;
            Integer minute;
            String mssage;
            if (status) {
                hour = Integer.valueOf(config.getStartWorkTime().substring(0, config.getStartWorkTime().indexOf(":")));
                minute = Integer.valueOf(config.getStartWorkTime().substring(config.getStartWorkTime().indexOf(":") + 1));
                minute = minute + new Random().nextInt(config.getElasticTimeStart());
                mssage = "明日升旗时间";
            } else {
                hour = Integer.valueOf(config.getEndWorkTime().substring(0, config.getEndWorkTime().indexOf(":")));
                minute = Integer.valueOf(config.getEndWorkTime().substring(config.getEndWorkTime().indexOf(":") + 1));
                minute = minute + new Random().nextInt(config.getElasticTimeEnd());
                mssage = "今日降旗时间";
            }
            if (minute >= 60) {
                hour += 1;
                minute -= 60;
            }
            cron = "0 " + minute + " " + hour + " ? * *";
            log.info(mssage + hour + ":" + (String.valueOf(minute).length() == 1 ? 0 + String.valueOf(minute) : minute));
        } catch (Exception e) {
            exceptionStop(0, this.getClass().getName(), null);
        }
        return cron;
    }

    /**
     * 校验账号密码是否正确
     *
     * @return
     */
    public WebDriver checkPwd(boolean quit) {
        // 业务逻辑
        System.setProperty(driver, readUserFile().getChromedriverPath());
        System.setProperty("webdriver.chrome.silentOutput", "true");//去除日志
        Logger.getLogger("org.openqa.selenium").setLevel(Level.OFF);//去除日志
        WebDriver webDriver = new ChromeDriver();
        webDriver.get(url);
        try {
            Thread.sleep(3000);
            webDriver.findElement(By.id("username")).sendKeys(readUserFile().getAccount());
            webDriver.findElement(By.id("password")).sendKeys(readUserFile().getPassWord());
            webDriver.findElement(By.id("formsubmitButton")).click();
            Thread.sleep(3000);
            webDriver.findElement(By.className("check-in"));
            if (quit) {
                webDriver.quit();
            }
            return webDriver;
        } catch (Exception e) {
            count++;
            log.info("warning！语音警告第" + count + "次" + e.getMessage());
            exceptionStop(count, this.getClass().getName(), webDriver);
            this.checkPwd(true);
        }
        return webDriver;
    }

    /**
     * 校验是否为工作日
     *
     * @return
     */
    public boolean getHoliday() {
        try {
            try {
                SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
                String time = df.format(Long.valueOf(System.currentTimeMillis()));
                Calendar calendar = Calendar.getInstance();
                String week = String.valueOf(calendar.get(7) - 1);
                log.info("今天是" + time.substring(0, 4) + "年" + time.substring(4, 6) + "月" + time.substring(6) + "日,星期" + Arrays.asList(",一,二,三,四,五,六,日".split(",")).get(Integer.valueOf(week).intValue()));
                String dc = "https://tool.bitefu.net/jiari/?d=";
                String httpUrl = dc + time;
                StringBuffer sbf = new StringBuffer();
                URL url = new URL(httpUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.connect();
                InputStream is = connection.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                String strRead;
                while (!ObjectUtils.isEmpty(strRead = reader.readLine())) {
                    sbf.append(strRead);
                }
                reader.close();
                String result = sbf.toString();
                return (!"1".equals(result)) && (!"2".equals(result));
            } catch (Exception e) {
                exceptionStop(0, "getHoliday", null);
            }
            return false;

        } catch (Exception e) {
            exceptionStop(0, "getHoliday", null);
        }
        return false;
    }

    public void exceptionStop(int count, String method, WebDriver driver) {
        log.info("方法:" + method + "有异常,请联系开发人员及时处理！");
        driver.quit();
        if (count > 2) {
            log.info("严重警告！ 报警次数过多,将在3秒后自动终止此程序！");
            System.exit(0);
        }
    }

    public ConfigDTO readUserFile() {
        try {
            String encoding = "UTF-8";
            File file = new File("C:/user.txt");
            if (file.isFile() && file.exists()) {
                InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);//考虑到编码格式
                BufferedReader bufferedReader = new BufferedReader(read);
                String lineTxt;
                StringBuilder sb = new StringBuilder();
                while ((lineTxt = bufferedReader.readLine()) != null) {
                    sb.append(lineTxt);
                }
                read.close();
                JSONObject json = JSONObject.parseObject(sb.toString());
                ConfigDTO configDTO = new ConfigDTO();
                configDTO.setAccount(json.getString("账号"));
                configDTO.setPassWord(json.getString("密码"));
                configDTO.setChromedriverPath(json.getString("浏览器内核文件存放路径"));
                configDTO.setStartWorkTime(json.getString("上班打卡时间"));
                configDTO.setEndWorkTime(json.getString("下班打卡时间"));
                Integer elasticTimeStart = json.getInteger("上班弹性时间");
                Integer elasticTimeEnd = json.getInteger("下班弹性时间");
                boolean flag = json.getBoolean("是否取消节假日限制").booleanValue();
                configDTO.setFlag(flag);
                if ((elasticTimeStart.intValue() > 60) || (elasticTimeEnd.intValue() > 60)) {
                    throw new RuntimeException("弹性时间不得超过60分钟");
                }
                configDTO.setElasticTimeStart(elasticTimeStart);
                configDTO.setElasticTimeEnd(elasticTimeEnd);
                return configDTO;
            } else {
                throw new RuntimeException("未在C盘下找到user.txt文件");
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("读取文件内容出错,文件内容格式不正确");
        }
        return null;
    }
}
